package protocol

import (
	"encoding/binary"
	"math"
)

// Packet 包体
type Packet struct {
	head   MessageHeader
	length uint32
	data   []byte
}

func (p *Packet) Head() MessageHeader {
	return p.head
}

func (p *Packet) Data() []byte {
	return p.data
}

func newPacket(h MessageHeader, data []byte) *Packet {
	return &Packet{
		head:   h,
		length: uint32(len(data)),
		data:   data,
	}
}

// Encode 封装
func Encode(p *Packet) (b []byte, err error) {
	if p == nil {
		return nil, ErrDataIsEmpty
	}
	if len(b) > math.MaxUint32 {
		return nil, ErrDataTooLarge
	}
	head := make([]byte, 2)
	binary.BigEndian.PutUint16(head, uint16(p.head))
	length := make([]byte, 4)
	binary.BigEndian.PutUint32(length, p.length)
	b = append(b, head...)
	b = append(b, length...)
	b = append(b, p.data...)
	return
}

// Decode  解封装
func Decode(b []byte) (*Packet, error) {
	if len(b) < 2+4 {
		return nil, ErrBytesNoFit
	}
	head := MessageHeader(binary.BigEndian.Uint16(b[0:2]))
	length := binary.BigEndian.Uint32(b[2:6])

	if len(b) != int(2+4+length) {
		return nil, ErrBytesNoFit
	}
	return &Packet{
		head:   head,
		length: length,
		data:   b[6:],
	}, nil
}
